<?php
namespace app\swoole\controller;

use app\common\model\Users;
use app\swoole\service\IndexService;
use think\swoole\Server;

class Index extends Server
{
    // 监听所有地址
    protected $host = 'http://swoole.vovoqi.com';
    // 监听 9501 端口
    protected $port = 39999;
    // 指定运行模式为多进程
    protected $mode = SWOOLE_PROCESS;

    // 指定 socket 的类型为 ipv4 的 tcp socket
    protected $sockType = SWOOLE_SOCK_TCP;

    protected $serverType = 'socket';
    // 配置项
    protected $option = [
        /**
         *  设置启动的worker进程数
         *  业务代码是全异步非阻塞的，这里设置为CPU的1-4倍最合理
         *  业务代码为同步阻塞，需要根据请求响应时间和系统负载来调整
         */
        'worker_num' => 4,
        // 守护进程化
        'daemonize'  => 0,
        // 监听队列的长度
        'backlog'    => 128,

        'dispatch_mode'=> 5 #轮询模式:1  FD取模:2  忙闲分配:3  IP取模:4  UID取模:5
    ];

    public function onOpen($serv , $req)
    {
        $res = [];
        $data = $req->get;
        $userid = $data['userid'];
        $serv->bind($req->fd,$userid);
        $IS = IndexService::getInstance();
        if (!$IS) {
            $IS = IndexService::getInstance($serv,$req->fd,0);
        }

        foreach ($serv->connections as $fd){
            if ($fd == $req->fd){
                continue;
            }
            $res[] = $fd;
        }
        $IS->setType(0);
        $IS->setOnlines($res);
        $IS->sendMsg($req->fd);
    }
    
    /**
     * 当服务器收到来自客户端的数据帧时会回调此函数
     * @param @swoole_websocket_server $server
     * @param @swoole_websocket_frame $frame 是swoole_websocket_frame对象，包含了客户端发来的数据帧信息
     */
    public function onMessage($server, $frame)
    {
        trace($frame->data);
        $requestData = json_decode($frame->data,1);
        $IS = IndexService::getInstance();
        if (!$IS) {
            $IS = IndexService::getInstance($server,$frame->fd,3);
        }
        var_dump($closeFdArr = $server->heartbeat());
        if ((isset($requestData['init']) && $requestData['init']) || !$requestData['toWho']) {
            foreach ($server->connections as $key => $fd) {
                if ($fd == $frame->fd) {
                    continue;
                }
                $IS->setType(1);
                if (!isset($requestData['init'])) {
                    $IS->setType(3);
                    $IS->setData($requestData['data']);
                }
                $IS->setFrom($frame->fd);
                $IS->sendMsg($fd);
            }
        }else{
            $IS->setType(3);
            $IS->setFrom($frame->fd);
            $IS->sendMsg($requestData['toWho']);
        }
    }

    public function onClose($server, $efd, $reactorId)
    {
        $IS = IndexService::getInstance();
        if (!$IS) {
            $IS = IndexService::getInstance($server,$efd,2);
        }
        foreach ($server->connections as $fd) {
            if ($fd == $efd){
                continue;
            }
            $IS->setType(2);
            $IS->setFrom($efd);
            $IS->sendMsg($fd);
        }
    }
}
